﻿using System;
using System.Collections.Generic;
using System.Linq;
using CommonLibrary.Helpers;
using CommonLibrary.Models;
using GeneticSharp.Domain;
using GeneticSharp.Domain.Mutations;
using GeneticSharp.Domain.Populations;
using GeneticSharp.Domain.Selections;
using GeneticSharp.Domain.Terminations;
using GeneticSharpDemo.Data;
using GeneticSharpDemo.Models;

namespace GeneticSharpDemo
{
    public class GeneticSharpAlgorithmDemo
    {
        public static List<Schedule> Start(string[] args)
        {
            //定义一个计时对象
            System.Diagnostics.Stopwatch oTime = new System.Diagnostics.Stopwatch();
            oTime.Start();//开始计时 

            //首先，做模型准备
            var chromeSomeCount = DataManage.Instance.JobAndProcList.Count * 2;//编码长度
            var selection = new EliteSelection();//精英
            var crossover = new PositionBaseSelfCrossover(DataManage.Instance.JobAndProcList.Count);//下半片编码进行交叉
            var mutation = new UniformMutation(DataManage.Instance.JobAndProcList.Select(x => x.Index).ToArray());//上半片编码进行变异
            var fitness = new MSOSFitness();//根据调度方案计算适应度
            var chromosome = new MSOSChromosome(DataManage.Instance.JobAndProcList.Count);//MSOS编码
            var population = new Population(50, 50, chromosome);//种群
            var ga = new GeneticAlgorithm(population, fitness, selection, crossover, mutation)
            {
                Termination = new OrTermination(
                    new TimeEvolvingTermination(TimeSpan.FromSeconds(3600)),
                     new FitnessStagnationTermination(500),
                    new FitnessThresholdTermination((double)1 / "04:00".GetTimePosByTimeStr())
                    )
            };

            Console.WriteLine("GA running...");
            ga.Start();
            oTime.Stop();//结束计时
            Console.WriteLine($"GA done in {ga.GenerationsNumber} generations,time : {oTime.Elapsed}");

            //string str = string.Empty;
            //((MSOSChromosome)ga.BestChromosome).NotScheduleRecord.ForEach(x => str += x);
            //Console.WriteLine($"NotSchedule:{str}");
            string str = string.Empty;
            ((MSOSChromosome)ga.BestChromosome).GetGenes().Skip(DataManage.Instance.JobAndProcList.Count).ToList().ForEach(x => str += x);
            Console.WriteLine($"GetGenes:{str}");

            foreach (var s in ((MSOSChromosome)ga.BestChromosome).ScheduleList)
            {
                Console.WriteLine(s);
            }

            Console.WriteLine(((MSOSChromosome)ga.BestChromosome).JobEndTimeMax.GetDateTimeByMinute());
            return ((MSOSChromosome) ga.BestChromosome).ScheduleList;

            //var form = new ResultForm();
            //form.InitData(((MSOSChromosome)ga.BestChromosome).ScheduleList);
            //form.ShowDialog();
            //form.InitThroat(FinalBest.ThroatUseInfo.AllTimesOfA, FinalBest.ThroatUseInfo.AllTimesOfB, FinalBest.ThroatUseInfo.AllTimesOfBToA);
            //form.ShowDialog();

            // var bestChromosome = ga.BestChromosome as MSOSChromosome;
            // Console.WriteLine("Best solution found is X:{0}, Y:{1} with {2} fitness.", bestChromosome.X, bestChromosome.Y, bestChromosome.Fitness);

            // Console.ReadKey();
        }


    }
}
